import { Element } from 'diagram-js/lib/model/Types';
import modelerStore from '@wf/components/bpmnjs/store/modeler';
// import { isAny } from 'bpmn-js/lib/features/modeling/util/ModelingUtil';
// import editorStore from '@wf/components/bpmnjs/store/editor';
import { is, getBusinessObject } from 'bpmn-js/lib/util/ModelUtil';
import { createModdleElement } from '@wf/components/bpmnjs/utils/BpmnExtensionElementsUtil';
import { ModdleElement } from 'bpmn-moddle';
import editor from '@wf/components/bpmnjs/store/editor'
// import { isIdValid } from '@wf/components/bpmnjs/utils/BpmnValidator'

interface AssigneeMultiInstanceParams {
  isSequential: Boolean;
  // completionCondition?: String;
}

// 设置审批候选人
export function getAssigneeValue(element: Element): string | undefined {
  return element.businessObject[`candidateUsers`];
}

export function setAssigneeValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    candidateUsers: value
  });
}

// 是否支持审批
export function isAssignee(element: BpmnElement): boolean {
  return is(element, 'bpmn:UserTask');
}

// 设置节点多实例属性
export function setLoopCharacteristics(element: Element, params: AssigneeMultiInstanceParams = { isSequential: false }) {
  const businessObject = getBusinessObject(element);
  // 会签/或签时要将父节点审批人属性带入
  const assignee = getAssigneeValue(element);
  const newParams = {
    ...params,
    collection: assignee
  };
  if (!businessObject.loopCharacteristics) {
    const loopCharacteristics = createModdleElement('bpmn:MultiInstanceLoopCharacteristics', newParams, businessObject);
    updateLoopCharacteristics(element, loopCharacteristics);
  } else {
    const loopCharacteristics = businessObject.get('loopCharacteristics');
    const store = modelerStore();
    const modeling = store.getModeling;
    modeling.updateModdleProperties(element, loopCharacteristics, newParams);
  }
}

// 获取多实例节点属性
export function getLoopCharacteristics(element: Element) {
  const businessObject = getBusinessObject(element);
  return businessObject['loopCharacteristics'];
}

// 更新多实例节点属性
export function updateLoopCharacteristics(element: Element, properties?: any) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    loopCharacteristics: properties
  });
}

// 设置完成条件节点值
export function setCompleteConditionValue(element: Element, value: String) {
  if (!value) {
    updateCompleteCondition(element);
  } else {
    const businessObject = getBusinessObject(element);
    const completionCondition = createModdleElement('bpmn:FormalExpression', { body: value }, businessObject.get('loopCharacteristics'));
    updateCompleteCondition(element, completionCondition);
  }
}

// 获取完成条件节点值
export function getCompleteConditionValue(element: Element) {
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const completionCondition = loopCharacteristics && loopCharacteristics.get('completionCondition');

  return completionCondition && completionCondition.body;
}

// 更新完成条件节点配置
export function updateCompleteCondition(element: Element, completionCondition?: string | ModdleElement) {
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateModdleProperties(element, loopCharacteristics, { ...loopCharacteristics, completionCondition });
  removeLoopCharacteristicsProp(element);
}

// 更新完条件节点之后删除冗余属性
export function removeLoopCharacteristicsProp(element: Element) {
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  // 删除节点的$attrs上的$type属性
  delete loopCharacteristics.$attrs.$type;
}

// 设置异步
export function getAsyncValue(element: Element): string | undefined {
  return element.businessObject['async'];
}

export function setAsyncValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    async: value
  });
}

// 设置补偿
export function getCompensationValue(element: Element): string | undefined {
  return element.businessObject['isForCompensation'];
}

export function setCompensationValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    isForCompensation: value
  });
}

// 设置独占
export function getFormFieldValidationValue(element: Element): string | undefined {
  return element.businessObject['formFieldValidation'];
}

export function setFormFieldValidationValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    formFieldValidation: value
  });
}

// 设置优先级
export function getPriorityValue(element: Element): number | undefined {
  return element.businessObject['priority'];
}

export function setPriorityValue(element: Element, value: number) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    priority: value
  });
}

// 设置跳过表达式
export function getSkipExpressionValue(element: Element): string | undefined {
  const prefix = editor().getProcessEngine
  return element.businessObject.$attrs[`${prefix}:skipExpression`]
}

export function setSkipExpressionValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;
  const prefix = editor().getProcessEngine

  modeling.updateProperties(element, {
    [`${prefix}:skipExpression`]: value
  });
}

// 设置基数
export function getLoopCardinalityValue(element: Element): string | undefined {
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const loopCardinality = loopCharacteristics && loopCharacteristics.get('loopCardinality');
  return loopCardinality && loopCardinality.body;
}

export function setLoopCardinalityValue(element: Element, value: string) {
  if (!value) {
    updateLoopCardinality(element);
  } else {
    const businessObject = getBusinessObject(element);
    const loopCardinality = createModdleElement('bpmn:FormalExpression', { body: value }, businessObject.get('loopCharacteristics'));
    updateLoopCardinality(element, loopCardinality);
  }
}

export function updateLoopCardinality(element: Element, loopCardinality?: string | ModdleElement) {
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateModdleProperties(element, loopCharacteristics, { ...loopCharacteristics, loopCardinality });
  removeLoopCharacteristicsProp(element);
}

// 设置集合
export function getCollectionValue(element: Element): string | undefined {
  return element.businessObject['loopCharacteristics'] ? element.businessObject['loopCharacteristics']['collection'] : undefined;
}

export function setCollectionValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const newProperties = {
    ...loopCharacteristics,
    collection: value
  }

  modeling.updateModdleProperties(element, loopCharacteristics, newProperties);
  removeLoopCharacteristicsProp(element);
}

// 设置元素变量
export function getVariableValue(element: Element): string | undefined {
  return element.businessObject['loopCharacteristics'] ? element.businessObject['loopCharacteristics']['elementVariable'] : undefined;
}

export function setVariableValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;
  const businessObject = getBusinessObject(element);
  const loopCharacteristics = businessObject.get('loopCharacteristics');
  const newProperties = {
    ...loopCharacteristics,
    elementVariable: value
  }

  modeling.updateModdleProperties(element, loopCharacteristics, newProperties);
  removeLoopCharacteristicsProp(element);
}

// 设置到期时间
export function getDueDateValue(element: Element): string | undefined {
  return element.businessObject['dueDate'];
}

export function setDueDateValue(element: Element, value: string) {
  const store = modelerStore();
  const modeling = store.getModeling;

  modeling.updateProperties(element, {
    dueDate: value
  });
}